package net.zjitc.link;

import net.domain.Student;
import net.zjitc.list.MyArrayList;
import net.zjitc.list.MyList;

public class MyLinkedList<T> implements MyList<T> {
    private int size;
    private Node<T> first;
    private Node<T> last;


    /**
     * 默认到最后
     *
     * @param data
     * @return
     */
    @Override
    public boolean add(T data) { //空、非空 情况处理是不一样的
        Node<T> node = new Node<>(data);
        linkLast((Node<T>) node);
        return true;
    }

    private void linkLast(Node<T> node) {
        if (first == null) {
            first = node;
            last = first;
            size++;
        } else {
            last.next = node;
            last = last.next;
            size++;
        }
    }

    /**
     * 指定位置插入数据
     *
     * @param index
     * @param data
     * @return
     */
    @Override
    public boolean add(int index, T data) {
        if (index < 0 || index > size) {
            throw new RuntimeException("插入下标越界");
        }
        //插入分三种情况：最后 最前，中间
        Node<T> node = new Node<T>(data);
        if (index == size) { //size==0? 判断是否为空？
            linkLast(node);
            return true;

        }
        if (index == 0) {
            // first
            node.next = first;
            first = node;
            size++;
            return true;
        }
        //如何找到前一个
        Node<T> p = first;
        for (int i = 0; i < index - 1; i++) {
            p = p.next;
        }
        //插入
        node.next = p.next;
        p.next = node;
        size++;

        return true;
    }

    /**
     * 第九周周二上课找人回答:
     * @param data
     * @return
     */
    @Override
    public T remove(T data) {
        //对象比较： ==
        //data.equals(node.data);
        Node<T> p = first;
        if (data == null){
             while (p!= null){
                 if (p.data == null){
                     //....删除
                  break;
                 }
                 p = p.next;
             }
        }else {
            while (p!= null){
                if (data.equals(p.data)){
                    //删除
                break;
                }
                p = p.next;
            }
        }
        return null;
    }

    /**
     * 删除指定位置元素
     * @param index 指定位置
     * @return 删除的数据
     */
    @Override
    public T remome(int index) {
        if (index<0 || index >= size){
            throw new RuntimeException("元素下标越界");
        }
        Node<T> p = first;
        T oldData = null;
        if(index == 0){
            first = p.next;
            p.next = null;
            size--;
            oldData = p.data;
        }else { //删除最后一个和中间处理方式是一样的，
            // 不一的地方在于删除最后一个时候需要修改last
            for (int i = 0; i < index-1; i++) {
                p = p.next;
            }
            //先取值，再删除
            oldData = p.next.data;
            p.next = p.next.next;//删除
            if (index == size-1){
                last = p;
            }
            size--;
        }
        return oldData;
    }

    /**
     * 修改指定位置的数据
     * @param index 指定位置
     * @param data  新数据
     * @return
     */
    @Override
    public boolean set(int index, T data) {
        if (index<0 || index >= size){
            throw new RuntimeException("元素下标越界");
        }
        Node<T> p = first;
        for (int i = 0; i < index; i++) {
            p = p.next;
        }
        p.data = data;
        return true;
    }

    /**
     * 查找指定位置的数据
     * @param index 指定位置
     * @return 指定位置的数据
     */
    @Override
    public T getValue(int index) {
        if (index<0 || index >= size){
            throw new RuntimeException("元素下标越界");
        }
        Node<T> p = first;
        for (int i = 0; i < index; i++) {
            p = p.next;
        }
        return p.data;
    }

    @Override
    public int size(){
        return size;
    }
}
